﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace JBeamLibrary.Types
{
    public struct Float3
    {
        #region Constants

        public static readonly Float3 Origin = new Float3(0f, 0f, 0f);
        public static readonly Float3 Invalid = new Float3(float.MinValue, float.MinValue, float.MinValue);

        #endregion

        #region Properties

        public float X { get; set; }
        public float Y { get; set; }
        public float Z { get; set; }

        public bool IsOrigin
        {
            get { return Equals(Origin); }
        }

        public bool IsValid
        {
            get { return !Equals(Invalid); }
        }

        #endregion

        #region CTORs

        public Float3(float x, float y, float z)
            : this()
        {
            X = x;
            Y = y;
            Z = z;
        }

        #endregion

        #region Methods

        public override bool Equals(object obj)
        {
            return
                obj is Float3 &&
                ((Float3)obj).X.Equals(X) &&
                ((Float3)obj).Y.Equals(Y) &&
                ((Float3)obj).Z.Equals(Z);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override string ToString()
        {
            return string.Format("{{X={0}; Y={1}; Z={2}}}", X, Y, Z);
        }

        public static Float3 Parse(string str)
        {
            var match = Regex.Match(str, "{X=([0-9,.]+); Y=([0-9,.]+); Z=([0-9,.]+)}");
            if (match.Success)
                return new Float3(
                    float.Parse(match.Groups[1].Value),
                    float.Parse(match.Groups[2].Value),
                    float.Parse(match.Groups[3].Value));
            throw new FormatException(string.Format("The string '{0}' cannot be converted in to a valid Float3 object.", str));
        }

        public static bool TryParse(string str, out Float3 val)
        {
            try
            {
                val = Parse(str);
                return true;
            }
            catch (FormatException)
            {
                val = Invalid;
                return false;
            }
        }

        #endregion
    }
}
